#include "SocketClient.h"
#include "SocketChannel.h"

SocketClient::SocketClient(SocketHandler *pSocketHandler, const char* host,
		int port, int recvTimeout) {
	LOGI("  ");
	mSocketChannel = null;
	mSocketHandler = null;
	if (pSocketHandler == NULL) {
		return;
	}
	mSocketHandler = pSocketHandler;

#if (defined(_WIN32))
	WSADATA wsaData;
	int iResult;
	// Initialize Winsock
	iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
	if (iResult != 0) {
		pSocketHandler->onErr(0, ERR_TIMEOUT_SOCKET_CONNECT);
		return;
	}
#endif
	SocketChannel* socket = new SocketChannel();
	mSocketChannel = socket;
	int isConnect = socket->connectChannel(0, host, port, recvTimeout);
	if (isConnect < 0 && pSocketHandler != null) {
		pSocketHandler->onErr(isConnect, ERR_TIMEOUT_SOCKET_CONNECT);
		return;
	}
}
SocketClient::~SocketClient() {
	LOGI("  ");
	mSocketChannel->close();
}
int SocketClient::recv() {
	Buf buf;
//	int recv = mSocketChannel->recvData(buf.data,BUF_MAX_SIZE);
	int recv = mSocketChannel->peek(buf.data, BUF_MAX_SIZE);

	if (recv <= 0) {
//		LOGI("peek no data recv:%d", recv);
		return recv;
	} else {
		int size = mSocketHandler->doDecode(mSocketChannel, buf.data, recv);
		if (size <= 0) {
			return size;
		}
		Packet* packet = (Packet*) malloc(size);
		if (packet == NULL) {
			LOGE("xx  OOM  xx");
			return 0;
		}
		memset(packet, 0, size);
		memcpy(packet->data, buf.data, size);
		return size;
	}
}
int SocketClient::recv(handlePacket handler) {
	Buf buf;
	int recv = mSocketChannel->peek(buf.data, BUF_MAX_SIZE);
	if (recv <= 0) {
//		LOGI("peek no data recv:%d", recv);
		return recv;
	} else {
//		LOGI("peek %d bytes ", recv);
		int size = mSocketHandler->doDecode(mSocketChannel, buf.data, recv);
		if (size <= 0) {
			return size;
		}
		if (size >= BUF_MAX_SIZE) {
			LOGW("Packet is > BUF_MAX_SIZE(%d)", BUF_MAX_SIZE);
			return BUF_MAX_SIZE;
		}
		Packet packet;
		memset(&packet, 0, sizeof(Packet));
		packet.size = size;
		memcpy(packet.data, buf.data, size);
		if (handler == NULL) {
			LOGW("handler is null");
			return size;
		}
		(*handler)(&packet);
		return size;
	}
}

int SocketClient::send(char* buf, int size) {
	LOGI("send :%d bytes", size);
	return mSocketChannel->sendData(buf, size);
}
int SocketClient::send(char* buf, int size, int cmd) {
	if (buf == null || size <= 0) {
		mSocketHandler->onErr(mSocketChannel->fd, ERR_ILL_PARMS);
		return 0;
	}
	if (cmd == 0) {
		return mSocketChannel->sendData(buf, size);
	}
	Buf sendbuf;
	int result = mSocketHandler->doEncode(mSocketChannel->fd, buf, size, cmd,
			sendbuf.data, BUF_MAX_SIZE);
	LOGI("  ");
	if (result < 0) {
		return result;
	}
	return mSocketChannel->sendData(sendbuf.data, result);
}

void SocketClient::handle(handlePacket handler) {
	if (packetQueue.empty() || handler == NULL) {
		LOGI("PacketQueue.empty()||handler==NULL");
	} else {
		Packet * packet = packetQueue.front();
		handler(packet);
		packetQueue.pop();
		free(packet);
		packet = NULL;
	}
}
void SocketClient::heartbeat(){
	LOGI("SocketClient::heartbeat ");
}
